home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-12-16 | 9.5 KB | 463 lines | [TEXT/CWIE] |
- // =================================================================================
- //
- // CEventSend.cpp ©1996 Microsoft Corporation All rights reserved.
- //
- // =================================================================================
-
- #include "ocheaders.h"
- #include "CEventClient.h"
-
-
- const Uint32 DefaultIdleRefCon = 1;
- const Int32 DefaultIdleTime = 60;
-
- //=====================================================================
- //
- // Static functions
-
- static void GetObjectPName (IUnknown* inSource, Str255 outName);
-
- //
- // GetObjectPName
- //
- // Retrieve the control's name and copy it into a pascal string
- //
-
- static void GetObjectPName (IUnknown* inSource, Str255 outName)
- {
- IControl* sourceObject = nil;
-
- // Snag the IControl interface
- if (inSource)
- inSource->QueryInterface(IID_IControl, &sourceObject);
-
- // Copy the name and convert it to a pascal string
- if (sourceObject) {
- sourceObject->GetID(255, (char *)outName);
- c2pstr((char *) outName);
- PLstrcat(outName, "\p:");
- sourceObject->Release();
- }
- else{
- PLstrcpy(outName, "\p");
- }
- }
-
-
- //
- // CEventClient::CEventClient
- //
-
- CEventClient::CEventClient(void) : CBaseControl()
- {
- mCookie = 0;
- mMessage = NULL;
- mNumMsgs = 0;
- mCurrentMsg = 0;
- }
-
-
- //
- // CEventClient::~CEventClient
- //
-
- CEventClient::~CEventClient()
- {
- if (mMessage)
- {
- DisposeHandle((Handle) mMessage);
- mMessage = NULL;
- }
- }
-
-
- //
- // CEventClient::IUnknown::QueryInterface
- //
- // Returns a pointer to the specified interface on a component to which a
- // client currently holds an interface pointer.
- //
-
- STDMETHODIMP
- CEventClient::QueryInterface(REFIID inRefID, void** outObj)
- {
- if ( inRefID == IID_IStandardEvents )
- {
- *outObj = (void*) (IStandardEvents*) this;
- AddRef();
-
- return S_OK;
- }
- else
- return CBaseControl::QueryInterface(inRefID, outObj);
- }
-
-
- //
- // CEventClient::IObjectWithSite::SetSite
- //
- STDMETHODIMP
- CEventClient::SetSite(IUnknown* inUnkSite)
- {
- ErrorCode Result = CBaseControl::SetSite(inUnkSite);
-
- if (mContainerSiteP)
- mContainerSiteP->SetIdleTime(DefaultIdleTime, DefaultIdleRefCon);
-
- return Result;
- }
-
-
- //
- // CEventClient::IControl::Draw
- //
-
- STDMETHODIMP
- CEventClient::Draw(DrawContext* inContext)
- {
- FontInfo fInfo;
- Int16 curX;
- Int16 curY;
- Int16 i;
- Int16 msgIndex;
- Char8 theState;
- RgnHandle saveClipRgn;
- Rect controlRect, newClipRect;
- Boolean8 overlap = false;
-
- if (inContext->DrawAspect != DVASPECT_CONTENT)
- return DV_E_DVASPECT;
-
- // Set the font and size
- ::TextFont(applFont);
- ::TextFace(0);
- ::TextMode(srcCopy);
- ::TextSize(9);
- ::GetFontInfo(&fInfo);
-
- // Erase the area and outline the frame
- ::EraseRect(&inContext->Location);
- ::PenSize(1, 1);
- ::FrameRect(&inContext->Location);
-
- // Save the current clip
- saveClipRgn = ::NewRgn();
- ::GetClip(saveClipRgn);
-
- controlRect = inContext->Location;
- ::InsetRect(&controlRect, 3, 3);
- overlap = SectRect(&controlRect, &((*saveClipRgn)->rgnBBox), &newClipRect);
-
- if (overlap)
- {
- // Reset the clip
- ::ClipRect(&newClipRect);
- }
-
- // Initialize the message storage, if not already done
- if (!mMessage) {
- InitMessages();
- }
-
- curX = inContext->Location.left+3;
- curY = inContext->Location.top+3;
-
- // Draw the messages, one on each line
- curY += fInfo.ascent;
-
- msgIndex = (mCurrentMsg + 1) % mNumMsgs;
- theState = ::HGetState((Handle) mMessage);
- ::HLock((Handle) mMessage);
-
- for (i = 1; i <= mNumMsgs; i++)
- {
- ::MoveTo(curX, curY);
- ::DrawString(*(*mMessage + msgIndex));
- curY += fInfo.ascent + fInfo.descent + fInfo.leading;
- msgIndex = (msgIndex + 1) % mNumMsgs;
- }
-
- ::HSetState((Handle) mMessage, theState);
-
- if (overlap)
- {
- // Restore the clip
- ::SetClip(saveClipRgn);
- }
- ::DisposeRgn(saveClipRgn);
-
- return S_OK;
- }
-
-
- //
- // CEventClient::IControl::DoIdle
- //
- STDMETHODIMP
- CEventClient::DoIdle(Uint32 inIdleRefCon)
- {
- #pragma unused (inIdleRefCon)
- // if the client site has been set and the advisory cookie has not,
- // enumerate the other controls in this container to find the one we want
- // to connect to
- if (mContainerSiteP && mCookie == 0)
- {
- IUnknown* testControl;
- IEnumUnknown* enumU;
-
- // if we don't have a container yet
- // Get it now
- if ( !mContainerP )
- {
- mContainerSiteP->GetContainer(&mContainerP);
- mContainerP->AddRef();
- }
-
- if ( mContainerP )
- {
- // Enumerate the objects
- if ( SUCCEEDED(mContainerP->EnumControls(nil, OLECONTF_EMBEDDINGS, &enumU)) )
- {
- IConnectionPointContainer* cpContainer = nil;
-
- while ( enumU->Next(1, &testControl, nil) == NOERROR )
- {
- // Try to get a connection point container from the control
- testControl->QueryInterface(IID_IConnectionPointContainer, (void**) &cpContainer);
-
- // if it has one, this may be it
- if ( cpContainer )
- {
- IConnectionPoint* cp = nil;
-
- // See if this connection point container
- // has a connection point with the outgoing interface we want
- cpContainer->FindConnectionPoint(IID_IStandardEvents, &cp);
-
- // if we got it, set an advise connection on the outgoing interface
- if ( cp )
- {
- cp->Advise((IControl*) this, &mCookie);
- mContainerSiteP->SetIdleTime(RemoveIdler, DefaultIdleRefCon);
- cp->Release();
- }
-
- cpContainer->Release();
- }
-
- testControl->Release();
- }
-
- // Don't forget to release
- enumU->Release();
- }
- else
- {
- mCookie = -1;
- mContainerSiteP->SetIdleTime(RemoveIdler, DefaultIdleRefCon);
- }
- }
- }
-
- return S_OK;
- }
-
-
- //
- // CEventClient::IStandardEvents::OnDoubleClick
- //
- STDMETHODIMP
- CEventClient::OnDoubleClick(IUnknown* inSource, PlatformEvent* inEvent)
- {
- #pragma unused (inEvent)
- Str255 theMessage;
-
- // Add <control_name>:OnDoubleClick message
- GetObjectPName(inSource, theMessage);
- PLstrcat(theMessage, "\pOnDoubleClick");
- AddMessage(theMessage);
- FinishEvent();
- return S_OK;
- }
-
- //
- // CEventClient::IStandardEvents::OnKeyDown
- //
- STDMETHODIMP
- CEventClient::OnKeyDown(IUnknown* inSource, PlatformEvent* inEvent)
- {
- Str255 theMessage;
- Char8 theKey;
-
- // Add <control_name>:OnKeyDown:<key> message
- theKey = inEvent->message & charCodeMask;
- GetObjectPName(inSource, theMessage);
- PLstrcat(theMessage, "\pOnKeyDown: ");
- theMessage[0]++;
- theMessage[theMessage[0]] = theKey;
- AddMessage(theMessage);
- FinishEvent();
- return S_OK;
- }
-
-
- //
- // CEventClient::IStandardEvents::OnAutoKey
- //
- STDMETHODIMP
- CEventClient::OnAutoKey(IUnknown* inSource, PlatformEvent* inEvent)
- {
- Str255 theMessage;
- Char8 theKey;
-
- // Add <control_name>:OnAutoKey:<key> message
- theKey = inEvent->message & charCodeMask;
- GetObjectPName(inSource, theMessage);
- PLstrcat(theMessage, "\pOnAutoKey: ");
- theMessage[0]++;
- theMessage[theMessage[0]] = theKey;
- AddMessage(theMessage);
- FinishEvent();
- return S_OK;
- }
-
-
- //
- // CEventClient::IStandardEvents::OnKeyUp
- //
- STDMETHODIMP
- CEventClient::OnKeyUp(IUnknown* inSource, PlatformEvent* inEvent)
- {
- Str255 theMessage;
- Char8 theKey;
-
- // Add <control_name>:OnKeyUp:<key> message
- theKey = inEvent->message & charCodeMask;
- GetObjectPName(inSource, theMessage);
- PLstrcat(theMessage, "\pOnKeyUp: ");
- theMessage[0]++;
- theMessage[theMessage[0]] = theKey;
- AddMessage(theMessage);
- FinishEvent();
- return S_OK;
- }
-
-
-
- //
- // CEventClient::IStandardEvents::OnMouseDown
- //
- STDMETHODIMP
- CEventClient::OnMouseDown(IUnknown* inSource, PlatformEvent* inEvent)
- {
- #pragma unused (inEvent)
- Str255 theMessage;
-
- // Add <control_name>:OnMouseDown message
- GetObjectPName(inSource, theMessage);
- PLstrcat(theMessage, "\pOnMouseDown");
- AddMessage(theMessage);
- FinishEvent();
- return S_OK;
- }
-
-
-
- //
- // CEventClient::IStandardEvents::OnMouseUp
- //
- STDMETHODIMP
- CEventClient::OnMouseUp(IUnknown* inSource, PlatformEvent* inEvent)
- {
- #pragma unused (inEvent)
- Str255 theMessage;
-
- // Add <control_name>:OnMouseUp message
- GetObjectPName(inSource, theMessage);
- PLstrcat(theMessage, "\pOnMouseUp");
- AddMessage(theMessage);
- FinishEvent();
- return S_OK;
- }
-
-
-
- //
- // CEventClient::FinishEvent
- //
- void CEventClient::FinishEvent(void)
- {
- InvalAllContexts();
- }
-
- //
- // CEventClient::AddMessage
- //
- void CEventClient::AddMessage(Str255 inMessage)
- {
- char theState;
-
- if (!mMessage)
- InitMessages();
-
- // Lock the message storage
- theState = ::HGetState((Handle) mMessage);
- ::HLock((Handle) mMessage);
-
- // Advance the message pointer
- mCurrentMsg++;
- if (mCurrentMsg >= mNumMsgs)
- mCurrentMsg = 0;
-
- // Copy the message into the message storage
- ::PLstrcpy(*(*mMessage + mCurrentMsg), inMessage);
-
- // Unlock the message storage
- ::HSetState((Handle) mMessage, theState);
- }
-
- //
- // CEventClient::InitMessages
- //
- void CEventClient::InitMessages(void)
- {
- // Initialize the message storage, if not already done
- if (!mMessage)
- {
- DrawContext Context = {BeginPortType};
- Int16 height = 0;
- FontInfo fInfo;
- Int32 index = 1;
-
- if (mContainerSiteP->AcquireContext(mActiveContext->GetContextID(), &Context) == S_OK)
- {
- // Set the font and size
- ::TextFont(applFont);
- ::TextFace(0);
- ::TextSize(9);
- ::GetFontInfo(&fInfo);
-
- // Figure the number of lines that can be displayed in the control
- height = Context.Location.bottom - Context.Location.top - 6;
- mNumMsgs = height/(fInfo.ascent + fInfo.descent + fInfo.leading);
-
- // Add one more line if the leading is the only part that won't fit
- if (height - mNumMsgs * (fInfo.ascent + fInfo.descent + fInfo.leading) >=
- (fInfo.ascent + fInfo.descent)) {
- mNumMsgs++;
- }
-
- // Allocate the memory
- if (mNumMsgs > 0)
- {
- mMessage = (Str255**) ::NewHandleClear(sizeof(Str255) * mNumMsgs);
- mCurrentMsg = mNumMsgs ? mNumMsgs - 1: 0;
- }
- else
- mNumMsgs = 0;
-
- mContainerSiteP->ReleaseContext(&Context);
- }
- }
- }
-